using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Reflection;
using System.Collections;
using System.Xml;
using System.Configuration;
using System.Xml.XPath;

namespace PipelineGenerator
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
        ArrayList _mapsInAssembly;
        private void btnMapLocate_Click(object sender, EventArgs e)
        {
            _mapsInAssembly = new ArrayList();
            
            System.Windows.Forms.OpenFileDialog _fileDialog = new System.Windows.Forms.OpenFileDialog();
            if (txtMapDLL.Text.Length > 0)
            {
                _fileDialog.InitialDirectory = txtMapDLL.Text;
            }

            _fileDialog.Title = "Locate Template File";
            _fileDialog.Filter = "BizTalk Compiled DLL (*.dll)|*.dll";
            DialogResult _result;
            _result = _fileDialog.ShowDialog();
            if (_result != DialogResult.Cancel)
            {
                txtMapDLL.Text = _fileDialog.FileName;
                loadActivities(_fileDialog.FileName);
            }
            
        }
        string partialMapAssembly = "";
        Dictionary<string, Type> _schemas = new Dictionary<string, Type>();
        private void loadActivities(string AssemblyLocation)
        {   
            //Try to load up the assembly
            Microsoft.XLANGs.BaseTypes.TransformBase _xform = null;
            Assembly _assembly = Assembly.LoadFile(AssemblyLocation);
            partialMapAssembly = _assembly.GetName().Name;
            Type[] _types = _assembly.GetTypes();
            foreach (Type typ in _assembly.GetTypes())
            {
                if (typ.BaseType.Name == "SchemaBase")
                {
                    _schemas.Add(typ.FullName, typ);
                }

                if (typ.BaseType.Name == "TransformBase")
                {
                    _mapsInAssembly.Add(typ);
                }
            }
            cboMap.DataSource = _mapsInAssembly;
            cboMap.DisplayMember = "FullName";
            if (_assembly.GlobalAssemblyCache)
            {
                lblGAC.Visible = true;
            }
            else
            {
                lblGAC.Visible = false;
            }
            btnViewXSL.Enabled = true;
        }
        Microsoft.XLANGs.BaseTypes.TransformBase _xform = null; 
        private void cboMap_SelectedIndexChanged(object sender, EventArgs e)
        {
            
            if (cboMap.SelectedItem != null)
            {
                //Instantiate an instance
                Type _typ = (Type)cboMap.SelectedItem;
                _xform = (Microsoft.XLANGs.BaseTypes.TransformBase)System.Activator.CreateInstance(_typ);
                
                //Can we find the schemas?
                Type _obj;
                Microsoft.XLANGs.BaseTypes.SchemaBase _sourceSchema;
                Microsoft.XLANGs.BaseTypes.SchemaBase _targetSchema;

                bool schemaFound = _schemas.TryGetValue(_xform.SourceSchemas[0], out _obj);
                if (schemaFound)
                {
                    _sourceSchema = (Microsoft.XLANGs.BaseTypes.SchemaBase)System.Activator.CreateInstance(_obj);
                    txtSrcSchemaNameSpace.Text = _sourceSchema.Schema.TargetNamespace;
                }
                
                txtSourceSchema.Text = _xform.SourceSchemas[0];
                txtDestSchema.Text = _xform.TargetSchemas[0];

            }
             
            //We need to select out the source schemas and destination schemas

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            cbActivityElementName.Items.Add("GeneralSystemProperties");
            cbActivityElementName.Items.Add("EDIProperties");
            cbActivityElementName.Items.Add("CustomProperties");
            //txtOutputDir.Text = Properties.Settings.Default.OutputDir;
            //Properties.Settings.Default.Reload();
            //ToolTips
            ToolTip _tip = new ToolTip();
            // Set up the delays for the ToolTip.
            _tip.AutoPopDelay = 5000;
            _tip.InitialDelay = 1000;
            _tip.ReshowDelay = 500;
            // Force the ToolTip text to be displayed whether or not the form is active.
            _tip.ShowAlways = true;

            // Set up the ToolTip text for the Button and Checkbox.
            //_tip.SetToolTip(this.txtOptionalFriendlyIdentifier, "Provide a string that uniquely identifies this activity.  This is used if the source document has a very generic root element name.  This is optional.");
            StringBuilder _bldr = new StringBuilder();
            _bldr.AppendLine("Common Questions Regarding this solution:");
            _bldr.AppendLine();
            _bldr.AppendLine("  Method Maps can have functiods that are string concatenate.");
            _bldr.AppendLine("      These Functoids should start with Constant: for data to be inserted automatically or just the method name like System.DateTime.UtcNow");
            _bldr.AppendLine();
            _bldr.AppendLine("  Build your Maps with Data, Context and Uploads in separate maps.");
            _bldr.AppendLine();
            _bldr.AppendLine("  If you are building against a map that has to be GACd such as in your BTS Project, please deploy then re-run this utility.");
            _bldr.AppendLine("      This utility often loads data from the GAC (Data Maps) so re-GACing will allow for a refresh.");
            _bldr.AppendLine();
            _bldr.AppendLine("  Be sure to place the Pipeline Component in the VALIDATE Receive and the ENCODE Send stages.");
            
            

            
            textDocs.Text = _bldr.ToString();
            
        }

        private void btnViewXSL_Click(object sender, EventArgs e)
        {
            System.IO.TextWriter _tw = new System.IO.StreamWriter(System.IO.Path.Combine(System.Environment.CurrentDirectory, "tempFile.xsl"),false,Encoding.Unicode);
            _tw.Write(_xform.XmlContent);
            _tw.Close();
            HTMLViewer _xslVw = new HTMLViewer(System.IO.Path.Combine(System.Environment.CurrentDirectory, "tempFile.xsl"));
            _xslVw.ShowDialog();
        }

        private void groupBox2_Enter(object sender, EventArgs e)
        {

        }
        Dictionary<string, string> _ContextList;
        
        private void btnCtxDLL_Click(object sender, EventArgs e)
        {
            if (cbActivityElementName.Text.ToString() == "")
            {
                MessageBox.Show("Please specify a unique name for the library you are about to add.\n\tThis name will be used in the generation of the XSD as a unique element name.");
                return;
            }
            if(_ContextList == null)
            {
                _ContextList = new Dictionary<string,string>();
            }
            //Add this to the list of selected DLL's to bring in
            System.Windows.Forms.OpenFileDialog _fileDialog = new System.Windows.Forms.OpenFileDialog();
    
            _fileDialog.Title = "Locate Template File";
            _fileDialog.Filter = "BizTalk Compiled DLL (*.dll)|*.dll";
            DialogResult _result = _fileDialog.ShowDialog();

            if (_result != DialogResult.Cancel)
            {
                BuildContextXSD(_fileDialog.FileName, cbActivityElementName.Text);
            }
            
           
        }
        private void BuildContextXSD(string fileName, string ElementName)
        {
            //Try to load up the assembly
            Assembly _assembly = Assembly.LoadFile(fileName);
            //we need to find the name of the Assembly

            Type[] _types = _assembly.GetTypes();

            int Ctr = 0;
            foreach (Type typ in _assembly.GetTypes())
            {

                if (typ.BaseType.Name == "MessageContextPropertyBase" || typ.BaseType.Name == "MessageDataPropertyBase")
                {

                    //Microsoft.XLANGs.BaseTypes.MessageContextPropertyBase _ctx = (Microsoft.XLANGs.BaseTypes.MessageContextPropertyBase)System.Activator.CreateInstance(typ);
                    
                    Ctr++;
                    
                }
            }
            //Now remove it from the context list if it is already there
            if (Ctr > 0)
            {
                if(_ContextList.ContainsKey(ElementName))
                {
                    _ContextList.Remove(ElementName);
                }
                _ContextList.Add(ElementName, fileName);
            }
            else
            {
                //remove the contextList and re-add
                _ContextList.Remove(ElementName);
                _ContextList.Add(ElementName, fileName);
            }
            foreach (KeyValuePair<string, string> info in _ContextList)
            {
                if (!CtxList.Items.Contains(info.Key))
                {
                    CtxList.Items.Add(info.Key);
                }
            }
            if (Ctr == 0)
            {
                MessageBox.Show("There were no Context Properties found in this DLL.");
            }
            
        }
        private void btnBuildContextXSD_Click(object sender, EventArgs e)
        {

        }
        private void btnCtxGenerator_Click(object sender, EventArgs e)
        {
            try
            {
                if (txtCtxXSD.Text == "")
                {
                    MessageBox.Show("Please specify a location to save the Generated XSD file.");
                }
                else
                {
                    ParsingLogic.ContextXSD.CTX_XSD_Builder _ctxBldr = new ParsingLogic.ContextXSD.CTX_XSD_Builder();
                    string ContextXSD = _ctxBldr.GetContextXSD(_ContextList, txtMetadataDir.Text);
                    System.Xml.XmlDocument _doc = new System.Xml.XmlDocument();
                    _doc.LoadXml(ContextXSD);
                    _doc.Save(txtCtxXSD.Text);
                }
                MessageBox.Show("Generation Complete");
            }
            catch (System.Exception emsg)
            {
                MessageBox.Show("Exception:" + emsg.Message);
            }
        }

        private void btnXLSExport_Click(object sender, EventArgs e)
        {
            //Add this to the list of selected DLL's to bring in
            System.Windows.Forms.OpenFileDialog _fileDialog = new System.Windows.Forms.OpenFileDialog();
            if (txtExcelExport.Text != "")
            {
                _fileDialog.InitialDirectory = System.IO.Path.GetDirectoryName(txtExcelExport.Text);
            }
            _fileDialog.Title = "Locate existing Excel Export File";
            _fileDialog.Filter = "BizTalk Excel BAM Export (.xml)|*.xml";
            DialogResult _result;
            _result = _fileDialog.ShowDialog();
            if (_result != DialogResult.Cancel)
            {
                txtExcelExport.Text = _fileDialog.FileName;
            }
        }

        private void btnGenerateBAMXSD_Click(object sender, EventArgs e)
        {
            try
            {
                if (!txtBAMXSD.Text.Contains(".xsd"))
                {
                    MessageBox.Show("Please completely define an XSD to create prior to generating the file.  The location specfified is not an XSD.");
                }
                else
                {
                    System.Xml.XmlDocument _exportXML = new System.Xml.XmlDocument();
                    _exportXML.Load(txtExcelExport.Text);
                    string outputXSD = BAM_XSD_Builder.BuildBAMXSD(_exportXML, txtBAMXSDNamespace.Text);
                    System.Xml.XmlDocument _doc = new System.Xml.XmlDocument();
                    _doc.LoadXml(outputXSD);
                    _doc.Save(txtBAMXSD.Text);
                }
                MessageBox.Show("Generation Complete");
            }
            catch (System.Exception emsg)
            {
                MessageBox.Show("Exception occured:" + emsg.Message);
            }
        }

        

        private void txtContextActivityName_TextChanged(object sender, EventArgs e)
        {
            btnCtxDLL.Enabled = true;
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {

        }

        private void rbDataComponentNo_CheckedChanged(object sender, EventArgs e)
        {
            if (rbDataComponentNo.Checked)
            {
                grpDataComponent.Enabled = false;
            }
            else
            {
                grpAllMessageTypes.Enabled = false;
                grpDataComponent.Enabled = true;
            }

        }

        private void btnGetExistingXSD_Click(object sender, EventArgs e)
        {
           
        }

        private void btnContextMap_Click(object sender, EventArgs e)
        {
            //Add this to the list of selected DLL's to bring in
            System.Windows.Forms.OpenFileDialog _fileDialog = new System.Windows.Forms.OpenFileDialog();

            if (txtContextMap.Text != "")
            {
                _fileDialog.InitialDirectory = System.IO.Path.GetDirectoryName(txtContextMap.Text);
            }
            _fileDialog.Title = "Locate existing Map";
            _fileDialog.Filter = "BizTalk existing Map (.btm)|*.btm";
            DialogResult _result;
            _result = _fileDialog.ShowDialog();
            if (_result != DialogResult.Cancel)
            {

                txtContextMap.Text = _fileDialog.FileName;
            }
        }

        private void btnMethodMap_Click(object sender, EventArgs e)
        {
            //Add this to the list of selected DLL's to bring in
            System.Windows.Forms.OpenFileDialog _fileDialog = new System.Windows.Forms.OpenFileDialog();

            _fileDialog.Title = "Locate existing Map";
            _fileDialog.Filter = "BizTalk existing Map (.btm)|*.btm";
            _fileDialog.ShowDialog();

            txtUploadMapFile.Text = _fileDialog.FileName;
        }

        private void rbAllMessage_CheckedChanged(object sender, EventArgs e)
        {
            if (rbAllMessage.Checked)
            {
                grpAllMessageTypes.Enabled = true;
                grpDataComponent.Enabled = false;
            }
            else
            {
                grpAllMessageTypes.Enabled = false;
            }
        }

        private void btnMapFile_Click(object sender, EventArgs e)
        {
            //Add this to the list of selected DLL's to bring in
            System.Windows.Forms.OpenFileDialog _fileDialog = new System.Windows.Forms.OpenFileDialog();
            
            
            _fileDialog.Title = "Locate existing Map";
            if (cboMap.SelectedItem != null)
            {
                if (cboMap.SelectedItem.ToString() != "")
                {
                    Type _typ = (Type)cboMap.SelectedItem;
                    _fileDialog.Filter = "BizTalk existing Map (.btm)|" + _typ.Name + ".btm";
                }
            }
            else
            {
                _fileDialog.Filter = "BizTalk existing Map (.btm)|*.btm";
            }
            if (txtDataBTMFile.Text != "")
            {
                _fileDialog.InitialDirectory = System.IO.Path.GetDirectoryName(txtDataBTMFile.Text);
            }
            DialogResult _result;
            _result = _fileDialog.ShowDialog();
            if (_result != DialogResult.Cancel)
            {
                txtDataBTMFile.Text = _fileDialog.FileName;
            }
        }

        private void rbDataComponentYes_CheckedChanged(object sender, EventArgs e)
        {
            if (rbDataComponentYes.Checked)
            {
                grpAllMessageTypes.Enabled = false;
                grpDataComponent.Enabled = true;
            }
        }

        private void btnLocateExcel_Click(object sender, EventArgs e)
        {
            //Add this to the list of selected DLL's to bring in
            System.Windows.Forms.OpenFileDialog _fileDialog = new System.Windows.Forms.OpenFileDialog();
            if (txtExistingBAMXSD.Text != "")
            {
                _fileDialog.InitialDirectory = System.IO.Path.GetDirectoryName(txtExistingBAMXSD.Text);
            }
            
            _fileDialog.Title = "Locate existing exported Excel XML";
            _fileDialog.Filter = "BAM Exported Excel XML (.xml)|*.xml";
            DialogResult _result;
            _result = _fileDialog.ShowDialog();
            if (_result != DialogResult.Cancel)
            {

                txtExistingBAMXSD.Text = _fileDialog.FileName;
                //Load up the document from the text file
                System.Xml.XmlDocument _doc = new System.Xml.XmlDocument();
                _doc.Load(txtExistingBAMXSD.Text);

                //Now do an xpath statement to find the activities
                XmlNamespaceManager _mgr = new XmlNamespaceManager(_doc.NameTable);
                _mgr.AddNamespace("ns0", "http://schemas.microsoft.com/BizTalkServer/2004/10/BAM");

                //Get the root document
                string xPath = "/ns0:BAMDefinition/ns0:Activity";


                XmlNodeList childNodes = _doc.SelectNodes(xPath, _mgr);
                foreach (XmlNode node in childNodes)
                {
                    cbActivityName.Items.Add(node.Attributes["Name"].Value);
                }
            }
        }

        private void btnGenerate_Click(object sender, EventArgs e)
        {
            try
            {
                ParsingLogic.CodeGenDriver _driver = new ParsingLogic.CodeGenDriver(txtOutputDir.Text, txtXSLTDirectory.Text, txtMetadataDir.Text);
                if (rbAllMessage.Checked)
                {
                    _driver.GenerateCode(rbUseStreamingXSL.Checked, null, null, null, txtContextMap.Text, txtUploadMapFile.Text, true, txtNamespace.Text, cbActivityName.Text, txtSrcSchemaNameSpace.Text);
                }
                else
                {
                    _driver.GenerateCode(rbUseStreamingXSL.Checked, txtDataBTMFile.Text, partialMapAssembly, cboMap.Text, txtContextMap.Text, txtUploadMapFile.Text, false, txtNamespace.Text, null, txtSrcSchemaNameSpace.Text);

                }
                MessageBox.Show("Generation Complete");
            }
            catch (System.Exception emsg)
            {
                MessageBox.Show("Exception:" + emsg.Message);
            }
        }

        private void btnOutputDir_Click(object sender, EventArgs e)
        {
            //Add this to the list of selected DLL's to bring in
            Helper.OpenDirectoryDialog _directoryDialog = new PipelineGenerator.Helper.OpenDirectoryDialog();
            
           txtOutputDir.Text =  _directoryDialog.GetFolder();
            

           
            
        }

        private void btnMetadatDir_Click(object sender, EventArgs e)
        {
            Helper.OpenDirectoryDialog _directoryDialog = new PipelineGenerator.Helper.OpenDirectoryDialog();
            txtMetadataDir.Text = _directoryDialog.GetFolder();
        }

        private void btnXLSTDirectory_Click(object sender, EventArgs e)
        {
            Helper.OpenDirectoryDialog _directoryDialog = new PipelineGenerator.Helper.OpenDirectoryDialog();
            txtXSLTDirectory.Text = _directoryDialog.GetFolder();
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            //Save the settings off
            Properties.Settings.Default.OutputDir = txtOutputDir.Text;
            Properties.Settings.Default.MetaDataDir = txtMetadataDir.Text;
            Properties.Settings.Default.Namespace = txtNamespace.Text;
            Properties.Settings.Default.XSLTDirectory = txtXSLTDirectory.Text;
            Properties.Settings.Default.MethodMap = txtUploadMapFile.Text;
            Properties.Settings.Default.ContextMap = txtContextMap.Text;
            Properties.Settings.Default.ExcelExportFile = txtExistingBAMXSD.Text;
            Properties.Settings.Default.CompiledBTSDLL = txtMapDLL.Text;
            Properties.Settings.Default.BAMXsdDestination = txtCtxXSD.Text;
            Properties.Settings.Default.ExcelExportFile = txtExistingBAMXSD.Text;
            Properties.Settings.Default.xlsExportFile = txtExcelExport.Text;
            Properties.Settings.Default.BAMXsdBuildLocation = txtBAMXSD.Text;
            Properties.Settings.Default.namespaceBAMXSD = txtBAMXSDNamespace.Text;
            Properties.Settings.Default.DataBTMFile = txtDataBTMFile.Text;

            Properties.Settings.Default.xlsFileName = txtExcelFile.Text;
            Properties.Settings.Default.csharpOutputLocation = txtBAMCLassOutput.Text;


            Properties.Settings.Default.Save();
        }

        private void cboMap_Click(object sender, EventArgs e)
        {
            if (txtMapDLL.Text != "")
            {
                if (_mapsInAssembly == null)
                {
                    _mapsInAssembly = new ArrayList();
                    loadActivities(txtMapDLL.Text);
                }
            }
        }

        private void btnViewXSD_Click(object sender, EventArgs e)
        {
            HTMLViewer _vw = new HTMLViewer(txtCtxXSD.Text);
            _vw.ShowDialog();
        }

        private void btnXSDLocate_Click(object sender, EventArgs e)
        {
            //Add this to the list of selected DLL's to bring in
            System.Windows.Forms.OpenFileDialog _fileDialog = new System.Windows.Forms.OpenFileDialog();
            if (txtCtxXSD.Text != "")
            {
                _fileDialog.InitialDirectory = System.IO.Path.GetDirectoryName(txtCtxXSD.Text);
            }
            _fileDialog.Title = "Locate new or existing Generated xsd  (Right Click to add New file .xsd)";
            _fileDialog.Filter = "XSD File (.xsd)|*.txt; *.xsd";
            DialogResult _result;
            _result = _fileDialog.ShowDialog();
            if (_result != DialogResult.Cancel)
            {
                txtCtxXSD.Text = _fileDialog.FileName;
            }
        }

        private void btnLocateOutputXSDDirectory_Click(object sender, EventArgs e)
        {
            //Add this to the list of selected DLL's to bring in
            Helper.OpenDirectoryDialog _directoryDialog = new PipelineGenerator.Helper.OpenDirectoryDialog();
            txtBAMXSD.Text =  _directoryDialog.GetFolder();
            txtBAMXSD.Text = txtBAMXSD.Text + @"\BAM_Activity_Schema.xsd";
        }


        private void btnContextUploadMap_Click(object sender, EventArgs e)
        {
           
        }

        private void btnLocateUploadMapFile_Click(object sender, EventArgs e)
        {
            //Add this to the list of selected DLL's to bring in
            System.Windows.Forms.OpenFileDialog _fileDialog = new System.Windows.Forms.OpenFileDialog();
            if (txtUploadMapFile.Text != "")
            {
                _fileDialog.InitialDirectory = System.IO.Path.GetDirectoryName(txtUploadMapFile.Text);            
            }
            _fileDialog.Title = "Locate new or existing BizTalk Map btm";
            _fileDialog.Filter = "Biztalk Map File (.btm)|*.btm";
            
            DialogResult _result;
            _result = _fileDialog.ShowDialog();
            if (_result != DialogResult.Cancel)
            {

                txtUploadMapFile.Text = _fileDialog.FileName;
            }
        }

        private void radioButton2_CheckedChanged(object sender, EventArgs e)
        {

        }

        private void btnLocateExcelFile_Click(object sender, EventArgs e)
        {
            System.Windows.Forms.OpenFileDialog _fileDialog = new System.Windows.Forms.OpenFileDialog();
            if (txtExcelFile.Text != "")
            {
                _fileDialog.InitialDirectory = System.IO.Path.GetDirectoryName(txtExcelFile.Text);
            }
            _fileDialog.Title = "Locate existing Excel File";
            _fileDialog.Filter = "BizTalk Excel File (.xls)|*.xls";
            DialogResult _result;
            _result = _fileDialog.ShowDialog();
            if (_result != DialogResult.Cancel)
            {
                txtExcelFile.Text = _fileDialog.FileName;
            }
        }

        private void btnLocateExportDirectory_Click(object sender, EventArgs e)
        {
            //Add this to the list of selected DLL's to bring in
            Helper.OpenDirectoryDialog _directoryDialog = new PipelineGenerator.Helper.OpenDirectoryDialog();
            txtBAMCLassOutput.Text = _directoryDialog.GetFolder();
            txtBAMCLassOutput.Text = txtBAMCLassOutput.Text + @"\BAM_Activity_Classes.cs";
        }

        private void btnGenerateClasses_Click(object sender, EventArgs e)
        {
            System.Diagnostics.Process _p = new System.Diagnostics.Process();
            _p.StartInfo.FileName = @"GenerateTypedBamAPI\GenerateTypedBamAPI.exe";
            string typeInfo = "";
            if (rbBAMOrchestrationMethod.Checked)
            {
                typeInfo = "Orchestration";
            }
            if(rbBAMBufferedMethod.Checked)
            {
                typeInfo = "Buffered";
            }
            if (rbDirect.Checked)
            {
                typeInfo = "Direct";
            }
            _p.StartInfo.Arguments = "\"" + txtExcelFile.Text + "\"";
            _p.StartInfo.Arguments = _p.StartInfo.Arguments + " " + "\"" + txtBAMCLassOutput.Text + "\"";
            _p.StartInfo.Arguments = _p.StartInfo.Arguments + " " + typeInfo;

            _p.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
            bool success = _p.Start();
            if (success)
            {
                MessageBox.Show("Process Successful");
            }
            else
            {
                MessageBox.Show("Process Failed.  Command line:" + _p.StartInfo.FileName + " " + _p.StartInfo.Arguments);
            }
        }

        
       
    }
}